Log In  
[back to top]


The following code block prints only the number 4, though I would expect it to print 2, 3, and 4.

do
 if (false) if (true) print(1)
 print(2)
 print(3)
end
print(4)

Only the outer if has this property, the inner if's scoping is fine. Similar behavior happens without the do block, I just included it to demonstrate the interaction of this behavior with "normal" Lua scopes.

3
2 comments



Here's yet another piece of simple data compression code:

Cart #simple_lz-0 | 2023-04-09 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
4

I wrote this for a (hopefully) upcoming player cart for RP-8 songs, in order to be able to pack as much RP-8 song data as possible into the spritesheet/map/sfx/music area of the cart. The compression technique is basically LZSS, with a couple of small changes / enhancements:

  • The code supports strings longer than 32kB - it will break them into 32kB blocks for compression and reassemble those blocks after decompression.
  • Literals are move-to-front encoded.
  • Match offsets, match lengths, and MTF literals are encoded using Elias gamma coding. The lowest N bits (N is a separately tunable parameter for offsets and literals, N is fixed to 0 for lengths) are encoded as usual, the remaining high-order bits are Elias gamma encoded.

[ Continue Reading.. ]

4
1 comment



This code uses 11% CPU according to Pico-8, but if I delete the v[0]=1 lines in the if false block it uses 7% CPU:

v={}
::_::
if false then
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
end
for i=0,1023 do
 v[0]=5
 v[0]=5
 v[0]=5
 v[0]=5
end
flip()
goto _

Other observations:

  • If I put the v[0]=1 lines in a for loop with a huge iteration count this code uses 7% CPU. (No bug.)
  • If I put this code into _update() or _draw() it uses 7% CPU. (No bug.)
  • Adding / removing v[0]=5 lines bumps CPU by roughly 3% per line.
  • Replacing v[0] with v[1] makes no difference.
  • Pico-8 does act on this CPU info, the contents of the if false block will affect whether Pico-8 visibly stutters if I add draw code and the non-executing lines push CPU over 100%.

[ Continue Reading.. ]

7
6 comments



I've already posted this on the Discord and a couple other places, but, well, why not post it here too? Randomly generated snowflakes for the season.

Cart #snowflake_generator_3d-0 | 2022-12-24 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
12

12
5 comments



This behavior feels possibly intentional, but I thought I'd check here just in case. If you run RP-8 with load #rp8, on loading carts, RP-8 gives the message unknown extcmd: set_title. If you ask it to open its folder with extcmd("folder"), it fails with a similar message. Both commands work fine if I save the cart to a .p8 and immediately re-load it. This is on 0.2.5c.

It'd be nice if folks could use load #rp8 to run RP-8 - even if this functionality doesn't end up enabled from Splore, perhaps it could work when loading carts by ID from the CLI? Also, is there some way to work around this and avoid showing the error message if the extcmd call isn't going to work?

At this point I'm wondering if I'll need to just point to Itch as the canonical download source for folks to get reliable results. That wouldn't be the end of the world, but offering a load #rp8 alternative would sure be nice!

3
0 comments



I've been working on a song in RP-8, and I've recently modified RP-8 to not just write song files to the clipboard, but also to timestamped save files on the desktop. After a long session of working on the song, I tried to save, and got a message about there being too many printh files.

I wouldn't have lost too much work - the whole reason I have this many files is that I've been checkpointing frequently - and I was able to get the data out of the clipboard, but it was still frustrating. This was a very long session, Pico-8 had probably been open for 12 hours or more while I'd been working off and on. Creating so many save files would certainly be a problem if Pico-8 had only been open for a few minutes, but over 12 hours I feel like it's not unreasonable?

I'd love for Pico-8 to reset its number of files / amount of data limits after some period of time, even an hour or two would be fine for my purposes.

I'd imagine this isn't super high prio, but it would be very nice. As I get closer to releasing RP-8 I'm starting to think more about awkward situations and edge cases I'll have to explain in the docs, and this would certainly be one of them. The really awkward thing about this one is that it undermines trust (since the user feels like they're losing work), and it's somewhat difficult to get around in a nice-feeling way...

[ Continue Reading.. ]

3
0 comments



As usual with PCM audio, be careful of your volume, and if this doesn't play back well in your browser, try it in desktop Pico-8. Earlier versions had filter instability problems that could result in loud sounds showing up out of nowhere - I think these are fixed now (I've let this play for over an hour with no problems) but I can't 100% promise it won't happen again.

Cart #acid_jam_512-3 | 2022-06-22 | Code ▽ | Embed ▽ | No License
20

An entry to the Pico-8 512-Char Jam. Kick, hat, acid.

Jam entry
Itch page

Update 1: Moved the delay time slightly off the beat. Also saved a few characters thanks to @SmellyFishstiks, which let me thicken the oscilloscope line.

[ Continue Reading.. ]

20
12 comments



Based on a request for help in the Pico-8 Discord, I ended up working on a rope/string/ribbon/chain/etc. simulation:

Cart #rope_sim_demo-0 | 2022-05-30 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
6

The behavior of the rope changes substantially depending on the gravity and drag settings.

This sim tries to model the object as inelastically as possible, although it's far from perfect in that regard. The rope here has 128 segments, which is very difficult to handle without (a) instability, (b) excess springiness in the rope, or (c) tons of damping. So i ended up having to write a slightly clever constraint solver (multigrid for n log n instead of n^2 performance), and I chose a step schedule that uses almost 100% CPU at 60fps. But if you use fewer segments and tune the solver differently, going down to 16 segments or so and using a less conservative step schedule, like one suggested in the cart comments, you can get the CPU usage closer to 5% at 60fps. That might be more suitable for inclusion in a game.

[ Continue Reading.. ]

6
0 comments



I was thinking about what's keeping Pico-8 from being a popular platform for scientific computing and high-end DSP ... and I realized: I can't think of a single FFT library for Pico-8! That must be the reason. So I wrote one:

Cart #pfft-2 | 2024-05-27 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
6

There are some comments at the top of the cart code on usage, if you want to copy/paste this into a project of your own for some reason. It's not too slow: you can do about 400 length-256 real FFTs per second, which is enough to get up to some audio shenanigans. (See next cart.) You can use the left/right arrow keys to switch modes between DFT, complex FFT, real FFT, and DCT in this demo, but be aware that if you happen to switch to DFT mode - it is sloooooooow and you may have to hold a button down for a while to get out of it. (DCT is also slow but ~3x faster than DFT.)

[ Continue Reading.. ]

6
9 comments



One of the things that's been driving me nuts while working on RP-8 has been how unstable the PCM audio output has felt. I can check (via logs or asserts) that, at 60fps, stat(108) is always above 256 and stat(1) never exceeds 0.9, and I'll still get occasional crackles or small time skips in the output. If I record the audio out with extcmd('audio_rec') these issues generally appear there as well - most often as small intervals of 0 samples. The one or two dropout cases I've been able to inspect in Audacity made it look like the dropout was in the low 10s of milliseconds range. I have not yet been able to track down a skip on the Audacity waveform display.

I've been trying to chase down the bugs in my code, but today I instead tried RP-8 - specifically the current BBS version, #rp8-2 - on two machines that aren't my normal development machine. It was rock solid. Flawless. (Or, well, nearly flawless, just heard a dropout on the Intel Mac after leaving it running for 15 minutes, but the ARM Mac shows problems much earlier and more frequently than that.) My main development machine is an ARM Mac, and the two other machines I tried today were a Windows box and an Intel Mac. The only conclusion I can draw right now is that there's something wonky about Pico-8's PCM audio out on ARM Macs that causes it to skip and/or drop frames.

[ Continue Reading.. ]

0 comments



Hello! I thought I'd try to (slightly) clean up and post some utility functions I've found useful while working on RP-8. Maybe they'll be useful to others, maybe not. Let's see!

Cart #rp8utils-0 | 2022-04-16 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
1

There are three possibly-useful functions here, plus their support code. Note that in the name of token conservation, all of these functions have essentially no error checking and can blow up in various exciting ways if you feed them bad data (or if they have bugs). The code also isn't the cleanest - maybe I'll tidy it up eventually, but I don't think it's completely unreadable right now. Anyway, we've got:

  • stringify(), 114 tokens. This serializes structured data into a string - RP-8 uses this to save songs. Escapes binary. Both the string format and the binary escaping are completely nonstandard, but the string format at least looks vaguely similar to Lua literals.
  • parse(), 286 tokens (can be cut to 246 if you don't want eval). This takes a string and transforms it into structured data. RP-8 uses this to load songs, as well as to set up some of its internal data. Uses the same weird format and binary escaping as stringify(), although it also supports some variations and syntactical sugar. You can probably cut more tokens if you don't need to support large input strings or binary unescaping.
  • eval(), two versions - 428 tokens for interpreted, and 556 for "compiled", plus you need parse(). (Very loose use of the word "compile" here...) This evaluates a script in a vaguely LISP-formatted mini-language with Lua-ish behavior, and returns the result. RP-8 uses this to save tokens by encoding bulky logic that doesn't need to run fast, like UI init. This can help save tokens. Note that the token costs here are pretty squishy, since they depend on what builtins you want to define.

While this eval may help you save tokens, if you're really serious you should probably consider external build tools and bytecode. (For more on this, check out what @carlc27843 did with

[ Continue Reading.. ]

1
0 comments



v1.1.2 update: added loop jump hotkeys (v1.1.1) and fixed a crash bug.

RP-8 is a synthesizer and groovebox inspired by Propellerhead Software's classic soft synth, ReBirth RB-338. It has everything you need to make entire tracks: two paraphonic synthesizers, a drum machine, a pile of effects to process your sound, and an integrated song mode sequencer to pull everything together. The audio is lo-fi, 8 bits at 5.5kHz, giving the output a distinctively crunchy sound.

If you're nostalgic for the early era of soft synths, a fan of minimalist computing, an acid squelch connoisseur, or just someone who likes to discover new sounds: I made RP-8 for you.

You can find this cart, including native builds, at https://luchak.itch.io/rp8, or try it out below. Note that this cart works much better natively than on the web - see the Web section under Compatibility Notes below for more info.

Cart #rp8-23 | 2023-11-04 | Code ▽ | Embed ▽ | No License
74

[ Continue Reading.. ]

74
38 comments



(spoiler: turns out I was scribbling over memory I shouldn't have been ... including the RNG state)

I think I've discovered a strange issue with rnd() and mouse position:

Here, I'm just playing a snare hit over and over again. The snare is created by mixing a sine wave with noise, where the noise is generated by rnd(). (With separate envelopes applied to each component.) Notice that every time the mouse exits the top of the screen, the character of the sound changes, becoming more tonal.

I am virtually certain this is because rnd() is doing something strange. If I modify my audio chunk synthesis function (runs ~1x/frame, generating ~100 samples) to put srand(any_constant_value) at the beginning, I'll get the tonal effect every time. If I instead put this at the beginning:

seed=0
function audio_dochunk()
 srand(seed)
 seed+=1

... then I never get the tonal effect, which is the result I would expect. I have confirmed that this does not happen when the mouse exits the screen in any other direction.

[ Continue Reading.. ]

3
3 comments



This follows the classic Stable Fluids paper by Jos Stam. Use your mouse.

Cart #simple_smoke-13 | 2024-03-08 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
24

A few things that would make this better:

  • More optimization
  • Higher resolution (if possible)
  • monotonic cubic interpolation for advection (likely too expensive)
  • MAC grid (NOPE - saves a lot of time to backtrace all quantities from cell centers instead. A MAC grid would mitigate some of the boundary artifacts here, but it's just too slow.)
  • vorticity confinement (expensive, but probably the next most important thing)
  • better smoke vis - bilinear interpolation? (almost certainly too expensive)
  • higher resolution for smoke than for velocity?
  • other forces: gravity / heat / etc.

[ Continue Reading.. ]

24
15 comments



PB-0x

A demake of a software groovebox from decades past...

Pattern mode is nearly complete! There's a mixer section, pattern storage, and a few editing tools. Good thing, too, since I think I'm coming up at the limits of what the Pico-8 CPU can reliably handle.

WARNING: Be careful if you play this cart on the web! Audio playback performs poorly on some OS/browser combinations and you may get loud crackling or popping noises. Turn your volume down before playing for the first time. If you have browser trouble, try it in native Pico-8. Or in a forthcoming native app export that I'll probably put up somewhere!

Cart #pb0x-4 | 2022-01-03 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
18

Instructions

  • Arrow keys select buttons/knobs/etc.
  • Z/X change control values. (Z is down, X is up)

[ Continue Reading.. ]

18
11 comments



I just learned about the PCM interface, so I thought I'd do a little adventure into sound synthesis.

This cart is an experiment in building up an audio system that can run dataflow graphs built up from smaller generator and effect components. Here, I've used it to generate some plucked string sounds, mix those together, and then apply some delay to the result. The audio system needs some work and probably should implement audio processors as objects instead of coroutines (as coroutines it's annoying to send control signals once a processor has been created), but it's still kinda fun.

The code has a bunch of other areas that could use cleanup too, but coroutines vs. objects is probably the one big design issue that should get sorted out.

The one big audio-system-side thing that really helped here was trying to generate at least 128 samples per frame so long as I wasn't too far ahead of the audio system's needs. This really helped smooth out maximum CPU usage, since without that tweak I was sometimes generating 256 samples and sometimes 0.

[ Continue Reading.. ]

19
11 comments



Cart #notepool-0 | 2021-12-11 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
7

Here's a little toy that makes sound. Balls bounce around the screen and make different noises when they collide with each other. You can nudge the white ball around with the arrow keys. I tried to add some very minor lighting effects on the balls and to make the sounds respond to the force imparted on each collision.

The code is, of course, a mess.

7
4 comments



Cart #44846 | 2017-10-02 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
2

I started playing around with the shallow water equations and got to something that's maybe a little bit fun. Arrow keys make waves, Z switches boundaries between (approximately) open and reflecting. My implementation mostly follows https://graphics.ethz.ch/Downloads/Publications/Tutorials/2008/Mue08/coursenotes.pdf .

Current limitations/known bugs:

  • Dissipates energy rapidly, although you'll probably only notice this if the boundaries are reflective.
  • No handling of dry regions. Weird things may happen if depth goes to 0!
  • Weird oscillations around both (nearly-)dry regions and shocks/big elevation changes. Not sure yet how much of this is attributable to bugs vs. limitations of the discretization I'm using.
  • Liquid volume is not conserved. Not really a meaningful concept with open boundaries, but pretty noticeable with reflective boundaries.
  • No wave breaking etc. Shallow water equations are a heightfield model and I don't think I'll get around to full liquids on PICO-8 any time soon. :)

I hope this cart is fun to play with! I'm hoping to fix a few of the items above, clean up the graphics a bit, and maybe find a way to build a little bit of a game around these dynamics.

2
2 comments



Cart #39954 | 2017-04-26 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
11

Started playing around with 2D sims - fluids seem hard to do at reasonable resolution given CPU constraints, but waves are just fine. More natural boat control and bilinear interpolation for wave rendering (more detail! less blocky!) both might make this more fun.

I'm also wondering if there's a racing game here where you can interact with the waves and they aren't just part of the scenery.

11
4 comments



Cart #39927 | 2017-04-25 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
4

A little cloud-based audio toy. Move your cloud around for different sounds. Would love to know what might make it more fun!

4
0 comments





Top    Load More Posts ->